モジュール:DropTables
ALRIGHT LET'S DO THIS --Initial writeup started by User:Falterfire on 7/1/2017 --Borrowing functions written by somebody else over on Module:VoidByReward --For reference: -- in DropData"Drops" local typeCol = 1 -- 1 = type (IE Survival, Capture) local catCol = 2 -- 2 = category (IE Hard, Derelict) local rotCol = 3 -- 3 = rotation (IE A, B) local numCol = 4 -- 4 = quantity (IE 1, 50) local itemCol = 5 -- 5 = item (IE Hornet Strike, Endo) local itemCatCol = 6 -- 6 = category (IE Mod, Resource) local rarityCol = 7 -- 7 = rarity (IE common, uncommon) local chanceCol = 8 -- 8 = drop chance (IE 15.03, 21.2) -- in DropData"Enemies" local eNameCol = 1 -- 1 = Name (IE Lancer) local eChance1Col = 2 -- 2 = Chance for that category (IE Mod % or Blueprint %) local eCountCol = 3 -- 3 = Number dropped. -1 means unknown local eItemCol = 4 -- 4 = Item (IE Hornet Strike, Dread Blueprint) local eItemCatCol = 5 -- 5 = Item Category (IE Mod, Blueprint) local eRarityCol = 6 -- 6 = Item Rarity (IE Common, Legendary) local eChance2Col = 7 -- 7 = The chance for this item to drop local eIgnoreCol = 8 -- 8 = if not nil and true, ignore this enemy local p = {} local DropData = mw.loadData( 'Module:DropTables/data' ) local script = require( "Module:Icon" ) local Shared = require( "Module:Shared" ) local Void = require( "Module:Void" ) local Mission = require( "Module:Missions" ) local Relics = require( "Module:VoidByReward") local function linkEnemy(EName) --Cut off enemy names before parentheses while linking local paren, trash = string.find(EName, "%(") local Result = "" if(paren ~= nil) then Result = ""..EName.."" elseif (EName "Fissure Corrupted Enemy") then Result = ""..EName.."" else Result = ""..EName.."" end return Result end --Sorts theTable based on the listed column local function tableSort(theTable, sortCol, ascend) local new function sorter(r1, r2) if(ascend) then return r1sortCol < r2sortCol else return r1sortCol > r2sortCol end end table.sort(theTable, sorter) end --Returns the real drop chance of a specific enemy drop --This involves combining chance to drop mod/blueprint with chance of that specific item dropping --So 3% Mod Chance + 37.94% Pressure Point chance = 1.1382% real chance local function getRealDropChance(EnemyDrop) local odds1 = EnemyDropeChance1Col local odds2 = EnemyDropeChance2Col local result = ((odds1 * odds2) / 100) return result end --Gets one of each mission type and returns the list local function getAllMissionTypes() local missions = {} local types = {} for typeName, typeData in Shared.skpairs(DropData"Categories") do for catName, cat in Shared.skpairs(typeData) do table.insert(missions, {Tier = cat.Alias}) end end return missions end local function getAllModDrops(enemyName) local drops = {} for i, d in pairs(DropData"Enemies") do if(deNameCol enemyName and (deItemCatCol "Mod" or deItemCatCol "Endo")) then table.insert(drops, d) end end return drops end local function getAllBlueprintDrops(enemyName) local drops = {} for i, d in pairs(DropData"Enemies") do if(deNameCol enemyName and (deItemCatCol "Blueprint")) then table.insert(drops, d) end end return drops end local function getAllEnemyDrops(enemyName) local drops = {} for i, d in pairs(DropData"Enemies") do if(deNameCol enemyName) then table.insert(drops, d) end end return drops end --Custom table sort for reward tables --WIP, initial rules: --Sort first by type, then alphabetically within type, then by quantity local function rewardTableSort(theTable) local new function sorter(r1, r2) if(r1itemCatCol r2itemCatCol) then if(r1itemCol r2itemCol) then return r1numCol < r2numCol else return r1itemCol < r2itemCol end else return r1itemCatCol < r2itemCatCol end end table.sort(theTable, sorter) end --Custom table sort for Enemy tables --Rules: --Sort first by Drop Chance, then alphabetically within Drop Chance with Endo being last local function enemyTableSort(theTable) local new function sorter(r1, r2) if(r1eChance2Col r2eChance2Col) then if(r1eItemCatCol r2eItemCatCol) then return r1eItemCol < r2eItemCol else return r1eItemCatCol > r2eItemCatCol end else return r1eChance2Col > r2eChance2Col end end table.sort(theTable, sorter) end local function getModLink(ModName) --Scorch and Seeker are both enemies and mods. Thanks DE. --Also Sanctuary as mod VS Simaris's thing if(ModName "Scorch" or ModName "Seeker" or ModName "Sanctuary") then return ""..ModName.."" else return ""..ModName.."" end end --Formats a string of text for a reward table --(NOTE: ALWAYS USES TWO COLUMNS) --Format is -- Icon Quantity Name with Link || Chance] -- With some slight variation based on drop type -- Variation is mostly helpful for getting the right icon local function formatDropString(drop) local result = "" local dropType = dropitemCatCol local iconText = "" if(dropType "Resource") then iconText = script._Resource(dropitemCol, nil, nil) if(dropitemCol "Mutalist Alad V Nav Coordinate") then result = result.."Mutalist Alad V Nav Coordinate" else result = result.."[["..dropitemCol.."]]" end elseif (dropType "Endo") then iconText = script._Item("Endo", nil, nil) result = result.."Endo" elseif (dropType "Mod") then iconText = script._Item("Mods", nil, nil) result = result..getModLink(dropitemCol) elseif (dropType "Relic") then local sp1, trash = string.find(dropitemCol, " ") local tier = string.sub(dropitemCol, 1, sp1 - 1) iconText = script._Item(tier, nil, "40x40") result = result.."[Relic|"..drop[itemCol.."]]" elseif (dropType "Credits") then iconText = script._Item("Credits", nil, nil) result = result.."Credit Cache" elseif (dropType "Blueprint") then local BPType = Shared.splitString(dropitemCol," ")2 local BPName = Shared.splitString(dropitemCol," ")1 if (BPName "Forma") then iconText = script._Item("Forma", nil, nil) elseif (BPType "Systems") then iconText = script._Item("Systems", nil, nil) elseif (BPType "Chassis") then iconText = script._Item("Chassis", nil, nil) elseif (BPType "Neuroptics") then iconText = script._Item("Neuroptics", nil, nil) elseif (BPType "Barrel") then iconText = script._Item("Barrel", nil, nil) elseif (BPType "Stock") then iconText = script._Item("Stock", nil, nil) elseif (BPType "Receiver") then iconText = script._Item("Receiver", nil, nil) elseif (BPType "Blade") then iconText = script._Item("Blade", nil, nil) else iconText = script._Item("Blueprint", nil, nil) end result = result.."[["..Shared.splitString(dropitemCol, " ")1.."|"..dropitemCol.."]]" else result = result..dropitemCol end if(dropnumCol > 1) then result = dropnumCol.." "..result end result = iconText.." "..result.." || "..dropchanceCol.."%" return result end --Returns a table of all rewards for a given mission, split by rotation local function getRewardsForMission(MissionType, MissionCat) if(MissionCat nil) then MissionType, MissionCat = Mission.getMissionFromAlias(MissionType) else MissionCat = Mission.getCategoryName(MissionType, MissionCat) end local RotA = {} local RotB = {} local RotC = {} for _, d in pairs(DropData"Drops") do local MType = dtypeCol local MCat = dcatCol local Rot = drotCol if(MType MissionType and MCat MissionCat) then if(Rot "A") then table.insert(RotA, d) elseif(Rot "B") then table.insert(RotB, d) else table.insert(RotC, d) end end end rewardTableSort(RotA) rewardTableSort(RotB) rewardTableSort(RotC) return {"A" = RotA, "B" = RotB, "C" = RotC} end --Gets the list of missions of a given type and sends them back local function getMissionsOfType(MissionType, MissionCat) if(MissionCat ~= nil) then MissionCat = Mission.getCategoryName(MissionType, MissionCat) MissionType = Mission.getAlias(MissionType, MissionCat) end local data = {} for _, m in Shared.skpairs(DropData"MissionDetails") do if(m.Tier MissionType) then table.insert(data, m) end end return data end --Returns the rewards for the A tier only for a mission --Handy for missions like Capture that have a single reward --Returns as rows for a table with two columns --See the existing Capture rewards section for an example function p.getSingleRotationRewards(frame) local MissionType = frame.args ~= nil and frame.args1 local MissionCat = frame.args ~= nil and frame.args2 local result = "" local data = getRewardsForMission(MissionType, MissionCat)"A" for i, drop in pairs(data) do result = result.."\n|-\n| "..formatDropString(drop) end return result end --Returns the rewards for a given mission/tier --Returns as rows for a table with six columns, two for each rotation --See existing Survival/Rewards/Normal_Mission for examples function p.getRewardTable(frame) local MissionType = frame.args ~= nil and frame.args1 local MissionCat = frame.args ~= nil and frame.args2 local result = "" local data = getRewardsForMission(MissionType, MissionCat) local RotA = data"A" local RotB = data"B" local RotC = data"C" local ACount = Shared.tableCount(RotA) local maxLen = ACount local BCount = Shared.tableCount(RotB) if(BCount > maxLen) then maxLen = BCount end local CCount = Shared.tableCount(RotC) if(CCount > maxLen) then maxLen = CCount end for i=1, maxLen, 1 do result = result.."\n|-" if(RotAi ~= nil) then result = result.."\n| align=\"right\" | "..formatDropString(RotAi) else result = result.."\n| || " end if(RotBi ~= nil) then result = result.."\n| align=\"right\" | "..formatDropString(RotBi) else result = result.."\n| || " end if(RotCi ~= nil) then result = result.."\n| align=\"right\" | "..formatDropString(RotCi) else result = result.."\n| || " end end if(MissionType "Sabotage" and MissionCat "Kuva Fortress") then result = result.."Category:KuvaSabotage" end return result end function p.getMissionList(frame) local MissionType = frame.args ~= nil and frame.args1 local MissionCat = frame.args ~= nil and frame.args2 result = "" local missions = getMissionsOfType(MissionType, MissionCat) for _, m in pairs(missions) do local typeName = m.Type result = result.."\n* "..m.Node..", "..m.Planet.."" --[(m.IsDarkSector 1) then result = result.." ([Dark Sector "..Mission.linkType(typeName)..")" else result = result.." ("..Mission.linkType(typeName)..")" end]] end return result end --Gets a list of missions with rewards for a given planet --Ignores 'Event' missions local function getMissionsForPlanet(Planet) local missions = {} for _, m in pairs(DropData"MissionDetails") do if (m.Planet Planet and m.Tier ~= nil) then table.insert(missions, m) end end return missions end local function getDropMissions(itemName) local Drops = {} for i, d in pairs(DropData"Drops") do if(ditemCol itemName) then table.insert(Drops, d) end end return Drops end local function getDropEnemies(itemName) local Drops = {} for i, d in pairs(DropData"Enemies") do if(string.upper(deItemCol) string.upper(itemName) and (deIgnoreCol nil or not deIgnoreCol)) then table.insert(Drops, d) end end return Drops end --Gets the table used on Void Relic/ByMission --Unlike getRewardTable, this is just the full table with all formatting --This is pretty ugly, but kinda have to do it this way --(Unless you have a better solution, in which case by all means go ahead and fix it) --(I'm not exactly a Lua expert or a UI expert) function p.getRelicTable(frame) --Okay, so first up, need to know which planet this is for local Planet = nil if(frame ~= nil) then Planet = frame.args ~= nil and frame.args1 or frame end --Planet nil is standing in for 'all planets', so adding option to explicitly call 'all' if(Planet ~= nil and (Planet "" or Planet "All")) then Planet = nil end --I have other functions to get the list of missions for all/planet --So calling that here local missions if(Planet nil) then missions = getAllMissionTypes() else missions = getMissionsForPlanet(Planet) end local tableRows = {} local Relics = {"Lith" = {}, "Meso" = {}, "Neo" = {}, "Axi" = {}} --Now for the 'fun' part: Getting the list for i, m in pairs(missions) do --For each mission, the first thing we're doing is setting up what it's called --Or more accurately, what it appears as in the chart local rowName = "" if(Planet nil) then local typeName, catName = Mission.getMissionFromAlias(m.Tier) --When showing all, the format is "Mission Name (Tier)" with link to mission type --For example, "Survival (Tier 1)" or "Spy (Lua)" rowName = Mission.linkType(typeName).." ("..Mission.getName(m.Tier)..")" else local placeName = m.Node --When showing a single planet, format is instead "Mission Name (Type)" --For example, "Rusalka (Capture)" --Mission type is still linked --Dark Sector is also linked if appropriate if (m.IsDarkSector 1) then rowName = placeName.." (DS "..Mission.linkType(m.Type)..")" else rowName = placeName.." ("..Mission.linkType(m.Type)..")" end end local thisRow = nil --This is where we get all the rewards for the mission local drops = getRewardsForMission(m.Tier) --Yeah, this is kinda clumsy --buuuuut it means I don't have to duplicate this loop three times --Please see disclaimer at top of function re:my not being a Lua Expert local rot = "A" --Need to know if this is a single rotation --Because if it is, just a checkmark instead of a letter local isSingleRot = Shared.tableCount(drops"B") 0 --For each mission, looping each rotation for i2=1, 3, 1 do --And each drop for each rotation for i3, d in pairs(dropsrot) do --We only care if it's a relic if(ditemCatCol "Relic") then --Set up the row if we don't have it yet --Mission will not be added to the grid unless it drops at least one relic --Avoids adding a row for something like Assassination that never gives relics if(thisRow nil) then thisRow = {} end --Example: "Lith A1 Relic" local RelicText = ditemCol --Example: {"Lith", "A1", "Relic"} local RelicBits = Shared.splitString(RelicText, " ") --Example: "Lith" local RTier = RelicBits1 --Example: "A1" local RName = RelicBits2 --Make sure the relevant entry exists if (thisRowRelicText nil) then thisRowRelicText = "" end --And then fill it in if (isSingleRot) then thisRowRelicText = "✔" else thisRowRelicText = thisRowRelicText..rot end --Also gotta add the Relic to our list if we don't have it yet if(RelicsRTierRName nil) then RelicsRTierRName = RelicText end end end rot = rot "A" and "B" or "C" end if ( thisRow ~= nil ) then tableRowsrowName = thisRow --Special duplicate row for Excavation 2/3 which matches Survival 2/3 if(Planet nil and (m.Tier "Survival2" or m.Tier "Survival3")) then local rowName2 = "Excavation ("..Mission.getName(m.Tier)..")" tableRowsrowName2 = thisRow end end end local result = "" local headerRow = "" --So this right here sets up the initial conditions of the table --If you want to change the styling, you've gotta do it here result = " " --And then ship it all back return result end --Function used for building Void Relic/DropLocation table function p.getRelicByLocation(frame) local tier = frame.args ~= nil and frame.args1 or frame local relicData = {} local missionData = {} local result = "" --As with most of my functions, breaking this into two parts: --First, gather all the data for i, d in pairs(DropData"Drops") do if(ditemCatCol "Relic") then --Example: "Lith A1 Relic" local RelicText = ditemCol --Example: {"Lith", "A1", "Relic"} local RelicBits = Shared.splitString(RelicText, " ") --Example: "Lith" local RTier = RelicBits1 --Example: "A1" local RName = RelicBits2 if(RTier tier) then local MType = dtypeCol local MCat = dcatCol local shortName = MType..MCat --Create an entry for this relic 'cause we don't have one yet if(relicDataRName nil) then relicDataRName = { Drops = {}, Rewards = Void.getRelic(RTier, RName).Drops} end table.insert(relicDataRName.Drops, d) end end end --Second, build the actual table being sent back local result result = " " result = result.."\n|\n"..rTable end result = result.."\n|}" return result end function p.getItemByMissionTable(frame) local theDrop = frame.args ~= nil and frame.args1 or frame local Drops = getDropMissions(theDrop) Shared.tableSort(Drops, typeCol, true) local rHeader rHeader = " " return rTable end function p.getItemByEnemyTable(frame) local theDrop = frame.args ~= nil and frame.args1 or frame local Drops = getDropEnemies(theDrop) Shared.tableSort(Drops, eNameCol, true) local rHeader rHeader = " " return rTable end function p.getItemDropList(frame) local theDrop = frame.args ~= nil and frame.args1 or frame local Drops = getDropMissions(theDrop) local checked = {} local result = "" if(Shared.tableCount(Drops) > 0) then local finalTable = {} result = "Missions:" Shared.tableSort(Drops, typeCol, true) for i, Drop in pairs(Drops) do if(DroptypeCol "Nightmare") then if(finalTable"Nightmare" nil) then finalTable"Nightmare" = {} end local difficulty if(DroprotCol "A") then difficulty = "Easy" elseif(DroprotCol "B") then difficulty = "Medium" else difficulty = "Hard" end table.insert(finalTable"Nightmare", difficulty) else local Alias = Mission.getAlias(DroptypeCol, DropcatCol) local MissionName = Mission.getShortName(DroptypeCol, DropcatCol) if(checkedAlias nil) then checkedAlias = 1 if(finalTable[DroptypeCol] nil) then finalTable[DroptypeCol] = {} end table.insert(finalTable[DroptypeCol], MissionName) if(Alias "Survival2" or Alias "Survival3") then if(finalTable"Excavation" nil) then finalTable"Excavation" = {} end table.insert(finalTable"Excavation", MissionName) end end end end local new function sorter(r1, r2) return r1 < r2 end table.sort(finalTable, sorter) for i, item in pairs(finalTable) do table.sort(item) result = result.." "..Mission.linkType(i).." ("..table.concat(item, ", ")..")" end end Drops = getDropEnemies(theDrop) if(Shared.tableCount(Drops) > 0) then Shared.tableSort(Drops, eNameCol, true) if(string.len(result) > 0) then result = result.." " end result = result.."Enemies:" for i, Drop in pairs(Drops) do result = result.." "..linkEnemy(DropeNameCol)..string.format(" (%.2f%%)", getRealDropChance(Drop)) end end return result end function p.getItemByEnemyCount(frame) local theDrop = frame.args ~= nil and frame.args1 or frame local Drops = getDropEnemies(theDrop) return Shared.tableCount(Drops) end function p.getItemByMissionCount(frame) local theDrop = frame.args ~= nil and frame.args1 or frame local Drops = getDropMissions(theDrop) return Shared.tableCount(Drops) end function p.getFullEnemyList(frame) local Enemies = {} local result = "All Enemies: " for i, d in pairs(DropData"Enemies") do local EName = deNameCol if(EnemiesEName nil) then EnemiesEName = 1 result = result.."\n* "..linkEnemy(EName) end end return result end function p.getEnemyModDrops(frame) local EnemyName = frame.args ~= nil and frame.args1 or frame local Drops = getAllModDrops(EnemyName) if(Shared.tableCount(Drops) 0) then return "None" end enemyTableSort(Drops) local result = "" for i, Drop in pairs(Drops) do if i > 1 then result = result.." " end local dChance = getRealDropChance(Drop) if(DropeItemCatCol "Endo") then result = result..DropeCountCol.." Endo" else result = result..getModLink(DropeItemCol) end result = result..string.format(" (%.2f%%)", dChance) end return result end function p.test(frame1, frame2) return Mission.getAlias(frame1, frame2) end return p